using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace TheUglyGame
{
    /// <summary>
    /// Dies ist der Haupttyp für Ihr Spiel
    /// </summary>
    public class Main : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        KeyboardState kbState, kbStateOld;
        MouseState msState, msStateOld;
        MainMenu mainmenu;

        Const.GameState currentGamestate, lastGamestate;
        Const.RunnigState currentRunState, lastRunState;
        Const.RunningModus currentRunModus, lastRunModus;

        public Main()
        {
            this.Window.Title = "The Ugly Game v0.01";
            this.IsMouseVisible = true;

            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            //TODO: in Konstanten abändern
            graphics.PreferredBackBufferWidth = 1280;      // Fensterbreite
            graphics.PreferredBackBufferHeight = 720;      // Fensterhöhe
        }

        /// <summary>
        /// Ermöglicht dem Spiel die Durchführung einer Initialisierung, die es benötigt, bevor es ausgeführt werden kann.
        /// Dort kann es erforderliche Dienste abfragen und nicht mit der Grafik
        /// verbundenen Content laden.  Bei Aufruf von base.Initialize werden alle Komponenten aufgezählt
        /// sowie initialisiert.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Fügen Sie Ihre Initialisierungslogik hier hinzu
            currentGamestate = Const.GameState.Intro;
            currentRunState = Const.RunnigState.Pause;
            currentRunModus = Const.RunningModus.OpenWorld;

            mainmenu = new MainMenu("Main", 0, 0, Const.WWidth, Const.WHeight, 3);

            base.Initialize();
        }

        /// <summary>
        /// LoadContent wird einmal pro Spiel aufgerufen und ist der Platz, wo
        /// Ihr gesamter Content geladen wird.
        /// </summary>
        protected override void LoadContent()
        {
            // Erstellen Sie einen neuen SpriteBatch, der zum Zeichnen von Texturen verwendet werden kann.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            mainmenu.SetSpritebatch(spriteBatch);
            mainmenu.Load(Content, spriteBatch);
            // TODO: Verwenden Sie this.Content, um Ihren Spiel-Content hier zu laden
        }

        /// <summary>
        /// UnloadContent wird einmal pro Spiel aufgerufen und ist der Ort, wo
        /// Ihr gesamter Content entladen wird.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Entladen Sie jeglichen Nicht-ContentManager-Content hier
        }

        /// <summary>
        /// Ermöglicht dem Spiel die Ausführung der Logik, wie zum Beispiel Aktualisierung der Welt,
        /// Überprüfung auf Kollisionen, Erfassung von Eingaben und Abspielen von Ton.
        /// </summary>
        /// <param name="gameTime">Bietet einen Schnappschuss der Timing-Werte.</param>
        protected override void Update(GameTime gameTime)
        {
            kbState = Keyboard.GetState();                                      //speichert aktuellen Tastaturstatus (welche Taste gedrückt etc.)
            msState = Mouse.GetState();                                         //speichert aktuellen Mousestatus (welche Taste gedrückt, Position etc.)

            // TODO: Fügen Sie Ihre Aktualisierungslogik hier hinzu
            switch (currentGamestate)
            {
                case Const.GameState.Intro:
                    lastGamestate = Const.GameState.Intro;
                    //IntroCode
                    currentGamestate = Const.GameState.MainMenu;
                    break;
                case Const.GameState.MainMenu:
                    lastGamestate = Const.GameState.MainMenu;
                    currentGamestate = mainmenu.Update(msState);
                    break;
                case Const.GameState.Credits:
                    //lastGamestate = Const.GameState.Credits;                  //wenn man die Credits beendet gehts zum letzten GameState zurück
                    //CreditsCode
                    currentGamestate = lastGamestate;
                    break;
                case Const.GameState.Outro:
                    //lastGamestate = Const.GameState.Outro;                    //wenn outro abgelaufen = Progende
                    //OutroCode
                    break;
                case Const.GameState.IngameMenu:
                    //lastGamestate = Const.GameState.IngameMenu;               //wird erst gesetzt wenn ich nicht ins Spiel zurück möchte
                    //IngameCode
                    break;
                case Const.GameState.ClassMenu:
                    lastGamestate = Const.GameState.ClassMenu;
                    //ClassMenuCode
                    currentGamestate = Const.GameState.Running;
                    break;
                case Const.GameState.Running:
                    lastGamestate = Const.GameState.Running;
                    currentRunState = Const.RunnigState.Run;
                    switch (currentRunModus)
                    {
                        case Const.RunningModus.OpenWorld:
                            lastRunModus = Const.RunningModus.OpenWorld;
                            switch (currentRunState)
                            {
                                case Const.RunnigState.Run:
                                    lastRunState = Const.RunnigState.Run;
                                    //Updatefunktionen für Openworld Objekte
                                    //currentRunModus = abhängig von dem was der Spieler macht
                                    //currentRunState = abhängig von dem was der Spieler macht
                                    break;
                                case Const.RunnigState.Pause:
                                    //Hier brauch nichts gemacht werden, evtl nur 'Pause' einblenden
                                    currentRunState = lastRunState;
                                    break;
                                case Const.RunnigState.BuySell:
                                    lastRunState = Const.RunnigState.BuySell;
                                    //Updatefunktionen fürs Ver/Kaufmenü
                                    currentRunState = Const.RunnigState.Run;
                                    break;
                                case Const.RunnigState.Conversation:
                                    lastRunState = Const.RunnigState.Conversation;
                                    //Updatefunktionen fürs Gespräche
                                    currentRunState = Const.RunnigState.Run;
                                    break;
                                case Const.RunnigState.Sequenz:
                                    lastRunState = Const.RunnigState.Sequenz;
                                    //SquenzCode
                                    currentRunState = Const.RunnigState.Run;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case Const.RunningModus.Fight:
                            lastRunModus = Const.RunningModus.Fight;
                            switch (currentRunState)
                            {
                                case Const.RunnigState.Run:
                                    lastRunState = Const.RunnigState.Run;
                                    //Updatefunktionen für Kampf Objekte
                                    //currentRunState = abhängig von dem was der Spieler macht
                                    //currentRunModus = Nachkampfende = Openworld
                                    break;
                                case Const.RunnigState.Pause:
                                    //Hier brauch nichts gemacht werden, evtl nur 'Pause' einblenden
                                    currentRunState = lastRunState;
                                    break;
                                case Const.RunnigState.Conversation:
                                    lastRunState = Const.RunnigState.Conversation;
                                    //Updatefunktionen fürs Gespräche
                                    currentRunState = Const.RunnigState.Run;
                                    break;
                                case Const.RunnigState.Sequenz:
                                    lastRunState = Const.RunnigState.Sequenz;
                                    //SquenzCode
                                    currentRunState = Const.RunnigState.Run;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
            kbStateOld = Keyboard.GetState();                                   //speichert geänderten Tastaturstatus (z.B. Taste losgelassen)
            msStateOld = Mouse.GetState();                                      //speichert geänderten Mousestatus (welche Taste losgelassen etc.)

            base.Update(gameTime);
        }

        /// <summary>
        /// Dies wird aufgerufen, wenn das Spiel selbst zeichnen soll.
        /// </summary>
        /// <param name="gameTime">Bietet einen Schnappschuss der Timing-Werte.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Fügen Sie Ihren Zeichnungscode hier hinzu
            spriteBatch.Begin();
            switch (currentGamestate)
            {
                case Const.GameState.Intro:
                    lastGamestate = Const.GameState.Intro;
                    //DrawIntro
                    currentGamestate = Const.GameState.MainMenu;
                    break;
                case Const.GameState.MainMenu:
                    mainmenu.Draw();
                    //DrawMain
                    break;
                case Const.GameState.Credits:
                    //DrawCredits
                    break;
                case Const.GameState.Outro:
                    //DrawOutro
                    break;
                case Const.GameState.IngameMenu:
                    //DrawIngameMenu
                    break;
                case Const.GameState.ClassMenu:
                    //DrawClassMenu
                    break;
                case Const.GameState.Running:
                    switch (currentRunModus)
                    {
                        case Const.RunningModus.OpenWorld:
                            switch (currentRunState)
                            {
                                case Const.RunnigState.Run:
                                    //Drawfunktionen für Openworld Objekte
                                    break;
                                case Const.RunnigState.Pause:
                                    //DrawPause
                                    break;
                                case Const.RunnigState.BuySell:
                                    //DrawBuySellMenu
                                    break;
                                case Const.RunnigState.Conversation:
                                    //DrawConversation
                                    break;
                                case Const.RunnigState.Sequenz:
                                    //DrawSequenz
                                    break;
                                default:
                                    break;
                            }
                            break;
                        case Const.RunningModus.Fight:
                            switch (currentRunState)
                            {
                                case Const.RunnigState.Run:
                                    //Drawfunktionen für Kampfobjekte
                                    break;
                                case Const.RunnigState.Pause:
                                    //DrawPause
                                    break;
                                case Const.RunnigState.Conversation:
                                    //DrawConversation
                                    break;
                                case Const.RunnigState.Sequenz:
                                    //DrawSequenz
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
